package ch.haclyon.driveimageview;


import ch.haclyon.ThreadPoolManager;

import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.Image;
import ohos.agp.components.LayoutScatter;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;

/**
 * The basic {@link DriveImageView}. This class includes all the methods you
 * need to modify your {@link DriveImageView}.
 *
 * @author Yannick Signer
 * @since 1.0.0
 */
public class DriveImageView extends DependentLayout {
    /**
     * driveLayout
     */
    private DriveImageViewLayout driveLayout;

    /**
     * imageView
     */
    private Image imageView;

    /**
     * driveImageModel
     */
    public DriveImageModel driveImageModel;

    /**
     * A new DriveImageView.
     *
     * @param context the {@link Context}
     * @author ysigner
     */
    public DriveImageView(Context context) {
        super(context);
        initialize(context);
    }

    /**
     * A new DriveImageView.
     *
     * @param context the {@link Context}
     * @param attrs   the {@link AttrSet}
     */
    public DriveImageView(Context context, AttrSet attrs) {
        super(context, attrs);
        initialize(context);
    }

    /**
     * A new DriveImageView.
     *
     * @param context      the {@link Context}
     * @param attrs        the {@link AttrSet}
     * @param defStyleAttr the defStyleAttr
     */
    public DriveImageView(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initialize(context);
    }

    /**
     * This initialises the main ohos widgets of the layout.
     *
     * @param context the {@link Context}
     */
    private void initialize(Context context) {
        LayoutScatter mInflater = LayoutScatter.getInstance(context);
        mInflater.parse(ResourceTable.Layout_driveimage, this, true);
        driveLayout = (DriveImageViewLayout) findComponentById(ResourceTable.Id_driveImageViewLayout);
        imageView = (Image) findComponentById(ResourceTable.Id_imageView);
    }

    /**
     * Returns the current {@link DriveImageModel} from the {@link DriveImageView}.
     *
     * @return the current model.
     */
    public DriveImageModel getDriveImageModel() {
        return driveImageModel;
    }

    /**
     * Sets the {@link DriveImageModel} to the {@link DriveImageView}.
     * This will cause the DriveImageView to redraw its figures and it also recalculates the size of the Canvas, because the size of the image can change.
     *
     * @param driveImageModel the {@link DriveImageModel}
     */
    public void setDriveImageModel(DriveImageModel driveImageModel) {
        this.driveImageModel = driveImageModel;
        if (driveImageModel.isDrawable()) {
            imageView.setPixelMap(driveImageModel.getDrawable());
        } else {
            imageView.setPixelMap(driveImageModel.getImageBitmap());
        }
        // 监听控件绘制完成,获取宽高
        ThreadPoolManager.getInstance().execute(() -> {
            while (true) {
                if (imageView.getEstimatedHeight() != 0) {
                    new EventHandler(EventRunner.getMainEventRunner()).postTask(() -> {
                        driveLayout.setImageViewHeight(imageView.getEstimatedHeight());
                        driveLayout.setImageViewWidth(imageView.getEstimatedWidth());
                    });
                    return;
                }
            }
        });
        driveLayout.setFolderText(driveImageModel.getFolderTitle());
        driveLayout.setMainText(driveImageModel.getMainTitle());
    }

    /**
     * Sets the background-color of the main figure on the canvas.
     *
     * @param backgroundColor the color as a Color-String
     */
    public void setBackgroundColor(String backgroundColor) {
        driveLayout.setBackgroundColour(backgroundColor);
    }

    /**
     * Sets the background-color of the divider figure.
     *
     * @param divideColor the color as a Color-String
     */
    public void setDivideColor(String divideColor) {
        driveLayout.setDivideColour(divideColor);
    }

    /**
     * Sets the text-color of both text's (main-text and folder-text)
     *
     * @param textColor the color as a Color-String.
     */
    public void setTextColor(String textColor) {
        driveLayout.setTextColour(textColor);
    }

    /**
     * Sets the opacity value of all the figures on the canvas.
     *
     * @param alphaValue the opacity (alpha) value in float, between 0f and 1f.
     */
    public void setAlphaValue(float alphaValue) {
        driveLayout.setAlphaValue(alphaValue);
    }

    /**
     * Sets the
     *
     * @param scale the
     */
    public void setImageScaleType(Image.ScaleMode scale) {
        imageView.setScaleMode(scale);
    }

    /**
     * This animates the text with a duration of 3 seconds.
     */
    public void animateText() {
        animateText(3000);
    }

    /**
     * This a animates a "blend-in" animation of the figure. The duration can be customised.
     *
     * @param duration The duration in milliseconds
     */
    public void animateText(int duration) {
        AnimatorValue animatorValue = new AnimatorValue();
        animatorValue.setDuration(duration);
        animatorValue.setValueUpdateListener((animatorValue1, value) -> {
            setAlphaValue(value);
        });
        animatorValue.start();
    }

    /**
     * Sets the custom height of the whole figure. This recalculates the text-sizes inside the Canvas.
     *
     * @param customHeight the desired height in dp.
     */
    public void setCustomHeight(float customHeight) {
        driveLayout.setCustomHeight(customHeight);
        driveLayout.setImageViewHeight(imageView.getEstimatedHeight());
        driveLayout.setImageViewWidth(imageView.getEstimatedWidth());
    }

    /**
     * Sets the spacing between the left border of the DriveImageView and the crack before the folder-text.
     *
     * @param customFolderSpacing the desired spacing in dp.
     */
    public void setCustomFolderSpacing(float customFolderSpacing) {
        driveLayout.setCustomFolderSpacing(customFolderSpacing);
    }

    /**
     * Returns the value of the folderCorner.
     *
     * @return the folderCorner value.
     */
    public float getFolderCorner() {
        return driveLayout.getFolderCorner();
    }

    /**
     * Sets the height and width of the folder corner.
     *
     * @param folderCorner height and width in dp.
     */
    public void setFolderCorner(float folderCorner) {
        driveLayout.setFolderCorner(folderCorner);
    }


}
